package com.tkm.advancedFunctions.highOrderFuns

fun main() {

    val intArray = IntArray(5) { it + 10 }
    intArray.forEach{ num -> println(num) }
    intArray.forEach { println(it) }
    intArray.forEach { println("Hello $it") }
    intArray.forEach(::println)

    needsFunc { println("Hello") }
    val func = returnFunc()
    func()

    cost {
        repeat(1000) { println("ZCCP $it") }
    }

    val fibonacciFn = fibonacci()
    repeat(10) {
        println(fibonacciFn())
    }

    val f = Fibonacci()
    repeat(10) { println(f.invoke()) }
}

//  函数作为参数
fun needsFunc(block: () -> Unit) {
    println("before block")
    block()
    println("after block")
}

//  函数作为返回值
fun returnFunc(): () -> Unit {
    return {
        println("Hello World")
    }
}

fun cost(block: () -> Unit) {
    val start = System.currentTimeMillis()
    block()
    val end = System.currentTimeMillis()
    println("costs: ${end - start}ms")
}

fun fibonacci(): () -> Long {
    //  fibonacci一旦被调用，其内部的变量将会暂时保存（参考：闭包的捕获）
    var first = 0L
    var second = 1L
    return {
        val next = first + second
        val current = first
        first = second
        second = next
        current
    }
}

class Fibonacci {
    private var first = 0L
    private var second = 1L

    fun invoke(): Long {
        val next = first + second
        val current = first
        first = second
        second = next
        return current
    }
}
